<template> 
  <div class="marine-monitor" :class="{ 'dark-mode': isDarkMode }"> 
    <!-- 三维可视化标题 --> 
    <header class="cyber-header"> 
      <div class="hologram-effect"></div> 
      <div class="header-content"> 
        <h1> 
          <span class="flicker">清泓智巡</span> 
          <span class="glitch">检测</span> 
          <sup>PRO</sup> 
        </h1> 
        <div class="status-indicators-container"> 
          <div class="status-indicators"> 
            <div class="signal-indicator"> 
              <div class="wave"></div> 
              <span>5G</span> 
            </div> 
            <div class="gps-indicator"> 
              <i class="icon-satellite"></i> 
              <span>GPS: 12</span> 
            </div> 
            <div class="connection-status" :class="{ 'connected': !isLoading && !connectionError, 'error': connectionError }"> 
              {{ connectionStatusText }} 
            </div> 
          </div> 
        </div> 
      </div> 
    </header> 
 
    <!-- 主监控区 --> 
    <main class="main-grid"> 
      <!-- 视频流主体 --> 
      <div class="primary-viewport" @mousemove="handleViewportHover" @mouseleave="resetViewportHover"> 
        <div class="viewport-overlay"></div> 
        <div class="video-container" :style="videoAspectStyle"> 
          <img 
            ref="videoStream" 
            :src="streamUrl" 
            class="mjpeg-stream" 
            @load="handleStreamLoad" 
            @error="handleStreamError" 
          /> 
          
          <!-- 增强现实叠加层 --> 
          <div class="ar-overlay"> 
            <div class="crosshair" :style="{ transform: crosshairTransform }"></div> 
            <div class="coordinate-display"> 
              <span>E{{ simulatedLng.toFixed(4)  }}</span> 
              <span>N{{ simulatedLat.toFixed(4)  }}</span> 
            </div> 
            <!-- 移除对象检测框 --> 
          </div> 
 
          <!-- 加载状态 --> 
          <transition name="fade"> 
            <div v-if="isLoading" class="loading-overlay"> 
              <div class="quantum-spinner"> 
                <div class="quantum-dot"></div> 
                <div class="quantum-dot"></div> 
                <div class="quantum-dot"></div> 
              </div> 
              <p class="loading-text">量子加密连接中...</p> 
            </div> 
          </transition> 
        </div> 
      </div> 
 
      <!-- 智能控制面板 --> 
      <aside class="control-panel" :class="{ 'hovered': isPanelHovered }" @mouseenter="isPanelHovered = true" @mouseleave="isPanelHovered = false"> 
        <div class="panel-section"> 
          <h3 class="panel-title"><i class="icon-ai"></i> 智能分析</h3> 
          <div class="ai-status"> 
            <div class="neon-progress"> 
              <div class="progress-bar" :style="{ width: aiProgress + '%' }"></div> 
              <span>威胁识别 {{ aiProgress }}%</span> 
            </div> 
            <div class="ai-metrics"> 
              <div class="metric-item"> 
                <span class="metric-label">检测对象</span> 
                <span class="metric-value">{{ detectedObjects.length  }}</span> 
              </div> 
              <div class="metric-item"> 
                <span class="metric-label">处理速度</span> 
                <span class="metric-value">42 FPS</span> 
              </div> 
            </div> 
          </div> 
        </div> 
 
        <div class="panel-section"> 
          <h3 class="panel-title"><i class="icon-settings"></i> 增强控制</h3> 
          <div class="enhance-controls"> 
            <div class="control-item"> 
              <label>红外模式</label> 
              <toggle-switch v-model="nightVision" @change="toggleNightVision" /> 
            </div> 
            <div class="control-item"> 
              <label>图像稳定</label> 
              <toggle-switch v-model="imageStabilization" /> 
            </div> 
            <div class="control-item"> 
              <label>目标追踪</label> 
              <toggle-switch v-model="objectTracking" /> 
            </div> 
          </div> 
        </div> 
 
        <div class="panel-section"> 
          <h3 class="panel-title"><i class="icon-connection"></i> 连接设置</h3> 
          <div class="connection-controls"> 
            <div class="control-item"> 
              <label>视频源地址</label> 
              <input 
                type="text" 
                v-model="streamBaseUrl" 
                class="url-input" 
                placeholder="http://192.168.x.x:5000" 
              /> 
            </div> 
            <button class="reconnect-btn" @click="reconnectStream"> 
              <i class="icon-refresh"></i> 重新连接 
            </button> 
          </div> 
        </div> 
      </aside> 
    </main> 
 
    <!-- 全息数据面板 --> 
    <footer class="holographic-footer" :class="{ 'expanded': isFooterExpanded }" @click="isFooterExpanded = !isFooterExpanded"> 
      <div class="footer-handle"> 
        <i class="icon-chevron-up"></i> 
      </div> 
      <div class="data-stream"> 
        <div class="data-item" v-for="(item, index) in telemetryData" :key="index"> 
          <div class="data-label">{{ item.label  }}</div> 
          <div class="data-value">{{ item.value  }}</div> 
          <div class="data-graph-container"> 
            <div 
              class="data-graph" 
              :style="{ width: item.percentage  + '%', 'background-color': item.color  }" 
              :class="{ 'pulse': item.alert  }" 
            ></div> 
          </div> 
        </div> 
      </div> 
    </footer> 
  </div> 
</template> 
 
<script setup> 
import { ref, computed, onMounted, onUnmounted, watch } from 'vue' 
import { useIntervalFn } from '@vueuse/core' 
 
// 配置变量 
const streamBaseUrl = ref('http://192.168.153.196:5000') 
const streamEndpoint = '/video_feed' 
const streamUrl = computed(() => `${streamBaseUrl.value}${streamEndpoint}`)  
 
// 流状态 
const videoStream = ref(null) 
const isLoading = ref(true) 
const connectionError = ref(false) 
const retryCount = ref(0) 
const connectionStatusText = computed(() => { 
  if (isLoading.value)  return '连接中...' 
  if (connectionError.value)  return '连接失败' 
  return '已连接' 
}) 
 
// 模拟数据 
const simulatedLng = ref(121.4737) 
const simulatedLat = ref(31.2304) 
const aiProgress = ref(0) 
const nightVision = ref(false) 
const imageStabilization = ref(true) 
const objectTracking = ref(true) 
const isDarkMode = ref(true) 
const isPanelHovered = ref(false) 
const isFooterExpanded = ref(true) 
const crosshairX = ref(50) 
const crosshairY = ref(50) 
const crosshairTransform = computed(() => `translate(${crosshairX.value}%,  ${crosshairY.value}%)`)  
 
// 检测对象模拟数据 
const detectedObjects = ref([ 
  { x: 30, y: 40, width: 15, height: 20, label: '船舶', confidence: 92, color: '#00f3ff' }, 
  { x: 60, y: 25, width: 10, height: 10, label: '浮标', confidence: 87, color: '#bc13fe' } 
]) 
 
// 遥测数据 
const telemetryData = ref([ 
  { label: '信号强度', value: '-72dBm', percentage: 85, color: '#00f3ff', alert: false }, 
  { label: '数据吞吐', value: '4.2Mbps', percentage: 62, color: '#00f3ff', alert: false }, 
  { label: '延迟', value: '128ms', percentage: 92, color: '#ff3e3e', alert: true }, 
  { label: 'CPU负载', value: '34%', percentage: 34, color: '#00f3ff', alert: false }, 
  { label: '内存使用', value: '2.4GB', percentage: 48, color: '#00f3ff', alert: false } 
]) 
 
// 视频比例控制 
const aspectRatio = ref('16:9') 
const videoAspectStyle = computed(() => { 
  const [w, h] = aspectRatio.value.split(':')  
  return { paddingBottom: `${(h / w) * 100}%` } 
}) 
 
// 流处理 
const handleStreamLoad = () => { 
  isLoading.value  = false 
  connectionError.value  = false 
  retryCount.value  = 0 
} 
 
const handleStreamError = () => { 
  if (retryCount.value  < 5) { 
    retryCount.value++  
    setTimeout(() => { 
      videoStream.value.src  = streamUrl.value  
    }, 1000 * retryCount.value)  
  } else { 
    isLoading.value  = false 
    connectionError.value  = true 
  } 
} 
 
const reconnectStream = () => { 
  isLoading.value  = true 
  connectionError.value  = false 
  retryCount.value  = 0 
  videoStream.value.src  = streamUrl.value  
} 
 
const toggleNightVision = (value) => { 
  if (value) { 
    document.documentElement.style.setProperty('--video-filter',  'grayscale(1) contrast(1.5) brightness(0.7)') 
  } else { 
    document.documentElement.style.setProperty('--video-filter',  'contrast(1.1) saturate(1.2)') 
  } 
} 
 
const handleViewportHover = (e) => { 
  const rect = e.target.getBoundingClientRect()  
  crosshairX.value  = ((e.clientX  - rect.left)  / rect.width)  * 100 
  crosshairY.value  = ((e.clientY  - rect.top)  / rect.height)  * 100 
} 
 
const resetViewportHover = () => { 
  crosshairX.value  = 50 
  crosshairY.value  = 50 
} 
 
// 数据模拟 
useIntervalFn(() => { 
  simulatedLng.value  += 0.0001 * (Math.random()  - 0.5) 
  simulatedLat.value  += 0.0001 * (Math.random()  - 0.5) 
  aiProgress.value  = Math.min(100,  aiProgress.value  + 2) 
  
  // 模拟数据波动 
  telemetryData.value.forEach(item  => { 
    const variation = Math.random()  * 10 - 5 
    item.percentage  = Math.max(0,  Math.min(100,  item.percentage  + variation)) 
    
    if (item.label  === '延迟') { 
      item.value  = `${Math.round(100  + Math.random()  * 50)}ms` 
      item.alert  = item.percentage  > 80 
    } else if (item.label  === '信号强度') { 
      item.value  = `-${Math.round(70  + Math.random()  * 15)}dBm` 
    } 
  }) 
  
  // 随机添加/移除检测对象 
  if (Math.random()  > 0.9 && detectedObjects.value.length  < 5) { 
    detectedObjects.value.push({  
      x: Math.random()  * 80 + 10, 
      y: Math.random()  * 60 + 10, 
      width: Math.random()  * 15 + 5, 
      height: Math.random()  * 15 + 5, 
      label: ['船舶', '浮标', '障碍物', '生物'][Math.floor(Math.random() * 4)], 
      confidence: Math.round(Math.random()  * 20 + 80), 
      color: `hsl(${Math.random()  * 360}, 100%, 70%)` 
    }) 
  } else if (Math.random()  > 0.95 && detectedObjects.value.length  > 0) { 
    detectedObjects.value.pop()  
  } 
}, 1500) 

// 热更新重连 
onMounted(() => { 
  if (import.meta.hot)  { 
    import.meta.hot.on('vite:beforeUpdate',  () => { 
      videoStream.value.src  = '' 
    }) 
  } 
  
  // 初始化CSS变量 
  document.documentElement.style.setProperty('--video-filter',  'contrast(1.1) saturate(1.2)') 
}) 
</script> 
 

<style lang="scss">
@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;700&family=Roboto+Mono:wght@300;400;500&display=swap');

:root {
  --bg-primary: #0a1929;
  --bg-secondary: #001e3c;
  --bg-tertiary: #071a2e;
  --bg-panel: #0a1f38;
  --text-primary: rgba(255, 255, 255, 0.95);
  --text-secondary: rgba(255, 255, 255, 0.7);
  --text-tertiary: rgba(255, 255, 255, 0.5);
  --accent-primary: #00f3ff;
  --accent-secondary: #bc13fe;
  --accent-tertiary: #3a86ff;
  --border-primary: rgba(0, 243, 255, 0.2);
  --border-secondary: rgba(188, 19, 254, 0.2);
  --shadow-primary: 0 0 15px rgba(0, 243, 255, 0.3);
  --shadow-secondary: 0 0 15px rgba(188, 19, 254, 0.3);
  --video-filter: contrast(1.1) saturate(1.2);
  --transition-speed: 0.3s;
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.marine-monitor {
  --bg-primary: #0a1929;
  --text-primary: rgba(255, 255, 255, 0.95);
  height: 100vh;
  background: var(--bg-primary);
  color: var(--text-primary);
  font-family: 'Roboto Mono', monospace;
  overflow: hidden;
  display: flex;
  flex-direction: column;

  &.dark-mode {
    --bg-primary: #001524;
    --bg-secondary: #000b17;
    --bg-panel: #071a2e;
    --text-primary: rgba(255, 255, 255, 0.85);
  }
}

.cyber-header {
  position: relative;
  padding: 1rem 2rem;
  background: linear-gradient(89deg, var(--bg-secondary) 0%, var(--bg-primary) 100%);
  border-bottom: 1px solid var(--border-primary);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
  z-index: 10;

  .header-content {
    display: flex;
    justify-content: space-between;
    align-items: center;
    max-width: 1800px;
    margin: 0 auto;
  }

  h1 {
    font: 700 2.2rem 'Orbitron', sans-serif;
    text-shadow: var(--shadow-primary);
    letter-spacing: 0.15em;
    color: var(--accent-primary);
    display: flex;
    align-items: center;
    gap: 0.5rem;

    .flicker {
      animation: flicker 3s infinite alternate;
    }

    .glitch {
      position: relative;
      color: var(--accent-secondary);
      text-shadow: var(--shadow-secondary);
      
      &::before {
        content: attr(data-text);
        position: absolute;
        left: -2px;
        text-shadow: 2px 0 var(--accent-secondary);
        clip: rect(0 900px 0 0);
        animation: glitch 3s infinite;
      }
    }

    sup {
      font-size: 1rem;
      margin-left: 0.5rem;
      color: var(--accent-tertiary);
    }
  }
}

.status-indicators-container {
  display: flex;
  align-items: center;
}

.status-indicators {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  background: rgba(0, 0, 0, 0.3);
  padding: 0.5rem 1rem;
  border-radius: 20px;
  border: 1px solid var(--border-primary);
  box-shadow: inset 0 0 10px rgba(0, 243, 255, 0.1);

  > div {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.9rem;
    color: var(--text-secondary);
  }

  .signal-indicator {
    .wave {
      width: 20px;
      height: 10px;
      position: relative;
      
      &::before {
        content: '';
        position: absolute;
        bottom: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background: radial-gradient(circle at center, var(--accent-primary) 0%, transparent 70%);
        animation: wave 1.5s infinite ease-in-out;
      }
    }
  }

  .gps-indicator {
    i {
      color: var(--accent-tertiary);
    }
  }

  .connection-status {
    padding: 0.3rem 0.8rem;
    border-radius: 15px;
    font-weight: 500;
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 1px;
    transition: all var(--transition-speed);

    &.connected {
      background: rgba(0, 200, 83, 0.2);
      color: #00c853;
      border: 1px solid rgba(0, 200, 83, 0.5);
    }

    &.error {
      background: rgba(255, 55, 55, 0.2);
      color: #ff3737;
      border: 1px solid rgba(255, 55, 55, 0.5);
    }
  }
}

.main-grid {
  display: grid;
  grid-template-columns: 1fr 350px;
  gap: 1.5rem;
  padding: 1.5rem;
  height: calc(100vh - 120px);
  max-width: 1800px;
  margin: 0 auto;
  width: 100%;
  transition: all var(--transition-speed);
}

.primary-viewport {
  position: relative;
  background: #000;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
  transition: all var(--transition-speed);
  transform: translateZ(0);
  border: 1px solid var(--border-primary);

  &:hover {
    box-shadow: 0 8px 25px rgba(0, 0, 0, 0.6);
    transform: translateY(-2px);
  }

  .viewport-overlay {
    position: absolute;
    inset: 0;
    background: linear-gradient(to bottom, rgba(0, 243, 255, 0.05) 0%, transparent 100%);
    pointer-events: none;
    z-index: 2;
  }
}

.video-container {
  position: relative;
  height: 0;
  width: 100%;
  
  .mjpeg-stream {
    position: absolute;
    width: 100%;
    height: 100%;
    object-fit: cover;
    filter: var(--video-filter);
    transition: filter 0.5s ease;
  }
}

.ar-overlay {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 3;

  .crosshair {
    position: absolute;
    width: 30px;
    height: 30px;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    border: 2px solid var(--accent-primary);
    border-radius: 50%;
    box-shadow: var(--shadow-primary);
    transition: transform 0.1s ease-out;
    
    &::before, &::after {
      content: '';
      position: absolute;
      background: var(--accent-primary);
    }
    
    &::before {
      width: 2px;
      height: 10px;
      left: 50%;
      top: -10px;
      transform: translateX(-50%);
    }
    
    &::after {
      width: 10px;
      height: 2px;
      top: 50%;
      right: -10px;
      transform: translateY(-50%);
    }
  }

  .coordinate-display {
    position: absolute;
    bottom: 15px;
    left: 15px;
    background: rgba(0, 0, 0, 0.7);
    padding: 0.5rem 1rem;
    border-radius: 4px;
    font-size: 0.9rem;
    color: var(--accent-primary);
    display: flex;
    gap: 1rem;
    border-left: 3px solid var(--accent-primary);
  }

  .object-detection {
    position: absolute;
    inset: 0;
  }

  .detection-box {
    position: absolute;
    border: 2px solid;
    box-shadow: 0 0 10px currentColor;
    
    .object-label {
      position: absolute;
      top: -25px;
      left: 0;
      background: rgba(0, 0, 0, 0.7);
      color: white;
      padding: 0.2rem 0.5rem;
      font-size: 0.8rem;
      border-radius: 3px;
      white-space: nowrap;
    }
  }
}

.control-panel {
  background: var(--bg-panel);
  border-radius: 8px;
  padding: 1.5rem;
  border: 1px solid var(--border-secondary);
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  transition: all var(--transition-speed);
  transform: translateZ(0);
  overflow: hidden;
  position: relative;

  &::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    background: linear-gradient(to right, var(--accent-primary), var(--accent-secondary));
  }

  &.hovered {
    transform: translateY(-2px);
    box-shadow: 0 8px 25px rgba(0, 0, 0, 0.4);
  }
}

.panel-section {
  h3 {
    font-family: 'Orbitron', sans-serif;
    font-size: 1.1rem;
    color: var(--accent-primary);
    margin-bottom: 1rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    letter-spacing: 1px;
    
    i {
      color: var(--accent-secondary);
    }
  }
}

.ai-status {
  background: rgba(0, 0, 0, 0.3);
  border-radius: 6px;
  padding: 1rem;
  border: 1px solid var(--border-primary);
  margin-bottom: 1.5rem;

  .neon-progress {
    height: 25px;
    background: rgba(0, 0, 0, 0.5);
    border-radius: 4px;
    margin-bottom: 1rem;
    position: relative;
    overflow: hidden;
    border: 1px solid var(--border-primary);

    .progress-bar {
      height: 100%;
      background: linear-gradient(to right, var(--accent-primary), var(--accent-secondary));
      border-radius: 3px;
      transition: width 0.5s ease;
      position: relative;
      
      &::after {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0.3) 50%, rgba(255,255,255,0) 100%);
        animation: shine 2s infinite;
      }
    }

    span {
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
      font-size: 0.8rem;
      font-weight: 500;
      color: white;
      text-shadow: 0 0 5px black;
    }
  }

  .ai-metrics {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;

    .metric-item {
      background: rgba(0, 0, 0, 0.3);
      border-radius: 4px;
      padding: 0.7rem;
      border: 1px solid var(--border-primary);
      display: flex;
      flex-direction: column;
      align-items: center;

      .metric-label {
        font-size: 0.8rem;
        color: var(--text-secondary);
        margin-bottom: 0.3rem;
      }

      .metric-value {
        font-family: 'Orbitron', sans-serif;
        font-size: 1.2rem;
        color: var(--accent-primary);
      }
    }
  }
}

.enhance-controls, .connection-controls {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.control-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.7rem;
  background: rgba(0, 0, 0, 0.2);
  border-radius: 4px;
  border: 1px solid var(--border-primary);
  transition: all var(--transition-speed);

  &:hover {
    background: rgba(0, 243, 255, 0.05);
    border-color: var(--accent-primary);
  }

  label {
    font-size: 0.9rem;
    color: var(--text-primary);
  }
}

.url-input {
  flex-grow: 1;
  background: rgba(0, 0, 0, 0.3);
  border: 1px solid var(--border-primary);
  border-radius: 4px;
  padding: 0.5rem 0.8rem;
  color: var(--text-primary);
  font-family: 'Roboto Mono', monospace;
  font-size: 0.9rem;
  transition: all var(--transition-speed);

  &:focus {
    outline: none;
    border-color: var(--accent-primary);
    box-shadow: 0 0 0 2px rgba(0, 243, 255, 0.2);
  }
}

.reconnect-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0.7rem;
  background: linear-gradient(to right, var(--accent-primary), var(--accent-tertiary));
  border: none;
  border-radius: 4px;
  color: black;
  font-weight: 500;
  cursor: pointer;
  transition: all var(--transition-speed);
  margin-top: 0.5rem;

  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 5px 15px rgba(0, 243, 255, 0.3);
  }

  i {
    font-size: 1rem;
  }
}

.holographic-footer {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background: var(--bg-tertiary);
  border-top: 1px solid var(--border-primary);
  box-shadow: 0 -5px 15px rgba(0, 0, 0, 0.3);
  transition: all 0.5s cubic-bezier(0.22, 1, 0.36, 1);
  z-index: 5;
  height: 80px;
  overflow: hidden;

  &.expanded {
    height: 150px;
    
    .footer-handle i {
      transform: rotate(180deg);
    }
  }

  .footer-handle {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 100px;
    height: 20px;
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: pointer;
    
    i {
      color: var(--text-secondary);
      transition: transform 0.3s ease;
      font-size: 1rem;
    }

    &:hover i {
      color: var(--accent-primary);
    }
  }
}

.data-stream {
  display: flex;
  height: 100%;
  padding: 1rem 2rem;
  align-items: flex-end;
  gap: 1.5rem;
  max-width: 1800px;
  margin: 0 auto;
  padding-top: 2rem;
}

.data-item {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-width: 120px;
  transition: all var(--transition-speed);

  &:hover {
    transform: translateY(-5px);
  }

  .data-label {
    font-size: 0.8rem;
    color: var(--text-secondary);
  }

  .data-value {
    font-family: 'Orbitron', sans-serif;
    font-size: 1.1rem;
    color: var(--text-primary);
  }

  .data-graph-container {
    height: 6px;
    background: rgba(255, 255, 255, 0.1);
    border-radius: 3px;
    overflow: hidden;
  }

  .data-graph {
    height: 100%;
    border-radius: 3px;
    transition: width 1s ease, background-color 0.3s ease;
    
    &.pulse {
      animation: pulse 2s infinite;
    }
  }
}

.loading-overlay {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.7);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  z-index: 10;
}

.quantum-spinner {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 10px;
  margin-bottom: 1rem;

  .quantum-dot {
    width: 12px;
    height: 12px;
    background: var(--accent-primary);
    border-radius: 50%;
    animation: bounce 1.4s infinite ease-in-out;
    
    &:nth-child(1) {
      animation-delay: -0.32s;
    }
    
    &:nth-child(2) {
      animation-delay: -0.16s;
    }
  }
}

.loading-text {
  color: var(--accent-primary);
  font-family: 'Orbitron', sans-serif;
  letter-spacing: 2px;
  font-size: 0.9rem;
  text-align: center;
}

/* Animations */
@keyframes flicker {
  0%, 19%, 21%, 23%, 25%, 54%, 56%, 100% {
    opacity: 1;
  }
  20%, 22%, 24%, 55% {
    opacity: 0.5;
  }
}

@keyframes glitch {
  0% { clip: rect(12px 9999px 22px 0) }
  25% { clip: rect(24px 9999px 56px 0) }
  50% { clip: rect(3px 9999px 34px 0) }
  75% { clip: rect(42px 9999px 68px 0) }
  100% { clip: rect(12px 9999px 22px 0) }
}

@keyframes wave {
  0%, 100% { height: 30%; }
  50% { height: 100%; }
}

@keyframes shine {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(100%); }
}

@keyframes bounce {
  0%, 80%, 100% { transform: scale(0); }
  40% { transform: scale(1); }
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}

.fade-enter-active, .fade-leave-active {
  transition: opacity 0.5s ease;
}

.fade-enter-from, .fade-leave-to {
  opacity: 0;
}

/* Responsive adjustments */
@media (max-width: 1200px) {
  .main-grid {
    grid-template-columns: 1fr;
    height: auto;
    min-height: calc(100vh - 120px);
  }
  
  .control-panel {
    grid-row: 1;
  }
  
  .holographic-footer {
    position: relative;
    margin-top: auto;
  }
}

@media (max-width: 768px) {
  .cyber-header {
    padding: 1rem;
    
    h1 {
      font-size: 1.5rem;
    }
  }
  
  .status-indicators {
    gap: 1rem;
    padding: 0.3rem 0.8rem;
    
    > div {
      font-size: 0.8rem;
    }
  }
  
  .main-grid {
    padding: 1rem;
    gap: 1rem;
  }
  
  .data-stream {
    flex-wrap: wrap;
    padding: 1rem;
    padding-top: 2rem;
  }
  
  .data-item {
    min-width: calc(50% - 1rem);
  }
}
</style>